package com.davidlife.framework.mybatis.dao.impl;

import com.davidlife.framework.mybatis.dao.UserDao;
import com.davidlife.framework.mybatis.domain.QueryVo;
import com.davidlife.framework.mybatis.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * 使用Mybatis开发Dao，通常有两个方法，即原始Dao开发方式和Mapper接口代理开发方式。
 * 而现在主流的开发方式是接口代理开发方式，这种方式总体上更加简便。
 *
 * 现在使用Mybatis自己写Dao实现的传统开发方式很少，基本都是使用getMapper这种Mapper接口代理开发方式，因为它更简便，且也能实现同样的功能。
 *
 * 这里演示 在自己写的UserDao接口实现类中，使用Mybatis实现CRUD的基本操作
 */
public class UserDaoImpl implements UserDao {

    private SqlSessionFactory factory;

    public UserDaoImpl(SqlSessionFactory factory) {
        this.factory = factory;
    }

    @Override
    public List<User> findAll() {
        //1. 使用工厂创建SqlSession对象
        SqlSession session = factory.openSession();
        //2. 使用session执行查询所有方法
        List<User> users = session.selectList("com.davidlife.framework.mybatis.dao.UserDao.findAll");
        //3. 关闭session
        session.close();
        //4. 返回查询结果
        return users;
    }

    @Override
    public void saveUser(User user) {
        SqlSession sqlSession = factory.openSession();
        int insert = sqlSession.insert("com.davidlife.framework.mybatis.dao.UserDao.saveUser", user);
        //注意：不要忘了执行 commit 操作
        sqlSession.commit();
        sqlSession.close();
    }

    @Override
    public void updateUser(User user) {
        SqlSession sqlSession = factory.openSession();
        int update = sqlSession.update("com.davidlife.framework.mybatis.dao.UserDao.updateUser", user);
        sqlSession.commit();
        sqlSession.close();
    }

    @Override
    public void deleteUser(Integer userId) {
        SqlSession sqlSession = factory.openSession();
        int delete = sqlSession.delete("com.davidlife.framework.mybatis.dao.UserDao.deleteUser", userId);
        sqlSession.commit();
        sqlSession.close();
    }

    @Override
    public User findById(Integer userId) {
        SqlSession sqlSession = factory.openSession();
        User user = sqlSession.selectOne("com.davidlife.framework.mybatis.dao.UserDao.findById", userId);
        sqlSession.close();
        return user;
    }

    @Override
    public List<User> findByUsername(String username) {
        SqlSession sqlSession = factory.openSession();
        List<User> users = sqlSession.selectList("com.davidlife.framework.mybatis.dao.UserDao.findByUsername", username);
        sqlSession.close();
        return users;
    }

    /**
     * 没用，只是为了避免报错
     * @param username
     */
    @Override
    public List<User> findByUsername2(String username) {
        return null;
    }

    @Override
    public int findTotal() {
        SqlSession sqlSession = factory.openSession();
        Integer total = sqlSession.selectOne("com.davidlife.framework.mybatis.dao.UserDao.findTotal");
        sqlSession.close();
        return total;
    }

    /**
     * 没用，只是为了避免报错
     * @param vo
     */
    @Override
    public List<User> findByVo(QueryVo vo) {
        return null;
    }

    /**
     * 没用，只是为了避免报错
     * @param user
     */
    @Override
    public List<User> findByCondition(User user) {
        return null;
    }

    /**
     * 没用，只是为了避免报错
     * @param vo
     */
    @Override
    public List<User> findUserInIds(QueryVo vo) {
        return null;
    }

    /**
     * 方便起见，这里就直接把测试代码也写在UserDaoImpl中了
     */
    public static void main(String[] args) throws IOException {
        //1. 读取配置文件
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2. 创建SqlSessionFactory工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(is);
        //3. 自己new一个UserDao对象，并传递一个工厂对象参数
        UserDao userDao = new UserDaoImpl(factory);
        //4. 使用自定义的UserDao实现类执行查询方法
        List<User> users = userDao.findAll();
        users.forEach(System.out::println);
        //5. 关闭资源
        is.close();
    }
}
